#ifndef PW_PBL_EXTARRAY_HPP
#define PW_PBL_EXTARRAY_HPP

#include "BitEnum.hpp"
#include <utility>

namespace pw_pbl
{
	template <typename IMP, typename... ID>
	struct ArrayTuple;

	template <typename IMP>
	struct ArrayTuple<IMP>
	{
	private:
		auto *_pFirst() const { return &static_cast<IMP *>(const_cast<ArrayTuple *>(this))->_f_(); }

	public:
		inline auto &operator[](size_t id) & { return _pFirst()[id]; }
		inline auto &&operator[](size_t id) && { return std::move(_pFirst()[id]); }
		inline const auto &operator[](size_t id) const & { return _pFirst()[id]; }
		inline const auto &&operator[](size_t id) const && { return std::move(_pFirst()[id]); }
	};

	template <typename IMP, ccBitEnum ID> requires(ID::ENatural)
	struct ArrayTuple<IMP, ID> : public ArrayTuple<IMP>
	{
		inline auto &operator[](ID id) & { return ArrayTuple<IMP>::operator[](pw_pbl::to_underlying(id)); }
		inline auto &&operator[](ID id) && { return std::move(ArrayTuple<IMP>::operator[](pw_pbl::to_underlying(id))); }
		inline const auto &operator[](ID id) const & { return ArrayTuple<IMP>::operator[](pw_pbl::to_underlying(id)); }
		inline const auto &&operator[](ID id) const && { return std::move(ArrayTuple<IMP>::operator[](pw_pbl::to_underlying(id))); }
	};

} // namespace pw_pbl

#endif // PW_PBL_EXTARRAY_HPP
